package com.wdy.dao.impl;

import java.sql.SQLException;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.wdy.dao.RepairDao;
import com.wdy.po.Repair;
import com.wdy.po.Tenement;
import com.wdy.util.TypeUtil;
import com.wdy.vo.Condition;
import com.wdy.vo.Page;
@SuppressWarnings("unchecked")
public class RepairDaoHibernateImpl extends HibernateDaoSupport implements RepairDao {
	
	private static final Log log = LogFactory.getLog(RepairDaoHibernateImpl.class);
	private static final String DATE = "date";
	
	//hibernate.lock
	
	public void attachClean(Repair instance) {
		log.debug("attaching clean Repair instance");
		try {
			getHibernateTemplate().lock(instance, LockMode.NONE);
			log.info("attach successful");
		} catch (DataAccessException e) {
			log.error("attach failed", e);
			throw e;
		}
	}
	//hibernate.saveOrUpdate
	
	public void attachDirty(Repair instance) {
		log.info("attaching dirty Repair instance");
		try {
			getHibernateTemplate().saveOrUpdate(instance);
			log.info("attach successful");
		} catch (DataAccessException e) {
			log.error("attach failed", e);
			throw e;
		}
		
	}
	//hibernate.delete
	
	public void delete(Repair persistentInstance) {
		log.info("deleting Repair instance");
		try {
			getHibernateTemplate().delete(persistentInstance);
			log.info("delete successful");
		} catch (DataAccessException e) {
			log.error("delete failed", e);
			throw e;
		}
		
		
	}
	//hibernate.find
	
	public List<Repair> findAll() {
		log.info("finding all");
		try {
			String queryString = "from Repair";
			List<Repair> result = (List<Repair>)getHibernateTemplate().find(queryString);
			log.info("find all successful,result size: " + result.size());
			return result;
		} catch (DataAccessException e) {
			log.error("find all failed", e);
			throw e;
		}
	}
	//hibernate.findByExample
	
	public List<Repair> findByExample(Repair instance) {
		log.info("finding Repair instance by example");
		try {
			List<Repair> result = (List<Repair>)getHibernateTemplate().findByExample(instance);
			log.info("find Repair instance by example successful, result size: " + result.size());
			return result;
		} catch (DataAccessException e) {
			log.error("find Repair instance by example failed", e);
			throw e;
		}
	}
	//hibernate.findById
	
	public Repair findById(String id) {
		return findById(id);
	}
	//hibernate.find

	public Repair findById(Integer id) {
		log.info("finding Repair instance by id");
		try {
			Repair repair = (Repair)getHibernateTemplate().get(Repair.class, id);
			log.info("find Repair instance by id successful");
			return repair;
		} catch (DataAccessException e) {
			log.error("find Repair instance by id failed", e);
			throw e;
		}
	}
	//hibernate.find
	
	public List<Repair> findByProperty(String propertyName, Object value) {
		log.info("finding Repair instance with property: " + propertyName + ", value: " + value);
		String queryString = "from Repair as model where model." + propertyName + "=?";
		try {
			List<Repair> result = (List<Repair>)getHibernateTemplate().find(queryString, value);
			log.info("find Repair instance by property successful, result size: " + result.size());
			return result;
		} catch (DataAccessException e) {
			log.error("find Repair instance by property failed", e);
			throw e;
		}
	}
	//findByProperty
	
	public List<Repair> findByDate(String value) {
		return findByProperty(DATE, value);
	}
	
	//hibernate.find
	public List<Tenement> findTenement(Object value) {
		log.info("finding Tenement instance by Repair.rid");
		List<Tenement> result;
		try {
			String queryString = "select t from Tenement as t inner join t.repairs r where r.rid = ?";
			result = (List<Tenement>)getHibernateTemplate().find(queryString,value);
			log.info("find Tenement instance by Repair.rid successful, result size: " + result.size());
			return result;
		} catch (DataAccessException e) {
			log.error("find Tenement instance by Repair.rid failed", e);
			throw e;
		}
	}
	
	//hibernate.merge
	public Repair merge(Repair detachedInstance) {
		log.info("merging Repair instance");
		try {
			Repair user = (Repair)getHibernateTemplate().merge(detachedInstance);
			log.info("merge Repair successful");
			return user;
		} catch (DataAccessException e) {
			log.error("merge Repair failed", e);
			throw e;
		}
	}
	//hibernate.save
	
	public void save(Repair transientInstance) {
		log.info("saving Repair instance");
		try {
			getHibernateTemplate().save(transientInstance);
			log.info("save Repair instance successful");
		} catch (DataAccessException e) {
			log.error("save Repair instance failed", e);
			throw e;
		}
	}
	
	@Override
	public DetachedCriteria getCriteria(List<Condition> conList) {
		// TODO Auto-gene}rated method stub
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(Repair.class);
		for (Condition con : conList) {
			String propertyName = con.getPropertyName();
			String relation = con.getRelation();
			Object[] tempArray = con.getValues();
			Object[] values = new Object[tempArray.length];
			int[] types = con.getTypes();
			values = TypeUtil.getType(tempArray, types);

			if ("eq".equals(relation)) {
				detachedCriteria.add(Restrictions.eq(propertyName, values[0]));
			} else if ("like".equals(relation)) {
				detachedCriteria.add(Restrictions.ilike(propertyName, "%"
						+ values[0] + "%"));
			} else if ("in".equals(relation)) {
				detachedCriteria.add(Restrictions.in(propertyName, values));
			} else if ("between".equals(relation)) {
				detachedCriteria.add(Restrictions.between(propertyName,
						values[0], values[1]));
			} else if ("ge".equals(relation)) {
				detachedCriteria.add(Restrictions.ge(propertyName, values[0]));
			} else if ("le".equals(relation)) {
				detachedCriteria.add(Restrictions.le(propertyName, values[0]));
			} else if ("ne".equals(relation)) {
				detachedCriteria.add(Restrictions.ne(propertyName, values[0]));
			}
		}
		return detachedCriteria;
	}

	@Override
	public List query(List<Condition> conList, final Page page) {
		// TODO Auto-generated method stub
		log.info("querying multiple for Repair instances");
		final DetachedCriteria detachedCriteria = getCriteria(conList);
		List result = (List) getHibernateTemplate().execute(
				new HibernateCallback() {
					@Override
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						// TODO Auto-generated method stub
						Criteria criteria = detachedCriteria
								.getExecutableCriteria(session);
						criteria.setFirstResult(page.getBeginIndex());
						criteria.setMaxResults(page.getEveryPage());
						criteria.addOrder(Order.asc("rid"));
						criteria.setProjection(null);
						return criteria.list();
					}
				});
		return result;
	}

	@Override
	public int getQueryCount(List<Condition> conList) {
		// TODO Auto-generated method stub
		final DetachedCriteria detachedCriteria = getCriteria(conList);
		List result = (List) getHibernateTemplate().execute(
				new HibernateCallback() {
					@Override
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						// TODO Auto-generated method stub
						Criteria criteria = detachedCriteria
								.getExecutableCriteria(session);
						criteria.setProjection(null);
						return criteria.list();
					}
				});
		return result.size();
	}

	@Override
	public void deleteBatch(final Object[] objects) {
		// TODO Auto-generated method stub
		getHibernateTemplate().execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				// TODO Auto-generated method stub
				String queryString = "delete from Repair where rid in (:rid)";
				Query query = session.createQuery(queryString);
				query.setParameterList("rid", objects);
				query.executeUpdate();
				return null;
			}
		});
	}

}
